package com.itxiao.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itxiao.config.RedisKeyConfig;
import com.itxiao.dao.*;
import com.itxiao.entity.*;
import com.itxiao.pojo.bo.Page;
import com.itxiao.pojo.bo.spu.SpecInfo;
import com.itxiao.pojo.dto.AddCartDto;
import com.itxiao.pojo.dto.AddCollectDto;
import com.itxiao.pojo.dto.AddOrderDto;
import com.itxiao.pojo.vo.OrderVo;
import com.itxiao.pojo.vo.R;
import com.itxiao.pojo.vo.spu.OrderSkuVo;
import com.itxiao.service.OrderItemService;
import com.itxiao.util.Price;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * (OrderItem)表服务实现类
 *
 * @author makejava
 * @since 2025-10-12 17:07:25
 */
@Service
public class OrderItemServiceImpl extends ServiceImpl<OrderItemDao, OrderItem> implements OrderItemService {
    @Resource
    private SpuDao spuDao;
    @Resource
    private SkuDao skuDao;
    @Resource
    private UserAddressDao userAddressDao;
    @Resource
    private StringRedisTemplate template;
    @Resource
    private  OrderItemDao orderItemDao;
    @Resource
    private  OrderSkuDao orderSkuDao;

    @Override
    public R queryList(Page page, String token) {
        List<OrderVo> orderVoList = new ArrayList<>();
        Map<String, Object> data = new HashMap<>();
        User sysUser = JSON.parseObject(
                template.opsForValue().get(RedisKeyConfig.AUTH_LOGIN_TOKEN + token),
                User.class
        );
        if (sysUser == null) {
            return R.fail("解析令牌失败");
        }
        page.setUserId(sysUser.getId());
        int total = orderItemDao.countByPage(page);
        List<OrderItem> orderItemList = orderItemDao.queryListByPage(page);
        if (orderItemList.isEmpty()) {
            data.put("list", orderVoList);
            data.put("total", total);
            return R.ok(data);
        }
        List<Long> orderIds = orderItemList.stream().map(OrderItem::getId).collect(Collectors.toList());
        List<OrderSku> orderSkuList = orderSkuDao.selectList(new LambdaQueryWrapper<>(OrderSku.class).in(OrderSku::getOrderId, orderIds));
        if (orderSkuList.isEmpty()) {
            return R.fail("查询订单商品失败");
        }
        //一个订单对应多个规格
        Map<Long, List<OrderSku>> orderItemsMap = orderSkuList.stream()
                .collect(Collectors.groupingBy(OrderSku::getOrderId));
        //组装数据返回前端
        for (OrderItem order : orderItemList) {
            List<OrderSku> items = orderItemsMap.getOrDefault(order.getId(), new ArrayList<>());
            List<OrderSkuVo> orderSkuVoList = new ArrayList<>();
            for (OrderSku item : items) {
                OrderSkuVo orderSkuVo = new OrderSkuVo();
                BeanUtils.copyProperties(item, orderSkuVo);
                orderSkuVo.setSalePrice(Price.IntToDecimal(item.getSalePrice()));
                orderSkuVoList.add(orderSkuVo);
            }
            OrderVo  orderVo = new OrderVo();
            BeanUtils.copyProperties(order,orderVo);
            UserAddress userAddress = null;
            if (order.getSnapAddress() != null && !order.getSnapAddress().trim().isEmpty()) {
                try {
                    userAddress = JSON.parseObject(order.getSnapAddress(), UserAddress.class);
                } catch (Exception e) {
                    log.warn("解析地址信息失败");
                    return R.fail("解析商品规格信息失败");
                }
            }
            orderVo.setUserAddress(userAddress);
            orderVo.setSkuList(orderSkuVoList);
            orderVo.setSalePrice(Price.IntToDecimal(order.getSalePrice()));
            orderVo.setTotalPrice(Price.IntToDecimal(order.getTotalPrice()));
            orderVo.setFreightPrice(Price.IntToDecimal(order.getFreightPrice()));
            orderVoList.add(orderVo);
        }
        data.put("list", orderVoList);
        data.put("total", total);
        return R.ok(data);
    }

    @Override
    public R queryStatus(String token) {
        User sysUser = JSON.parseObject(
                template.opsForValue().get(RedisKeyConfig.AUTH_LOGIN_TOKEN + token),
                User.class
        );
        if (sysUser == null) {
            return R.fail("解析令牌失败");
        }
        //根据 userId查出status 的分组数量
        List<Map<String, Object>> statusCounts = orderItemDao.selectStatusCountByUserId(sysUser.getId());
        return R.ok(statusCounts);
    }

    @Override
    public R queryDetail(Integer id, String token) {
        User sysUser = JSON.parseObject(
                template.opsForValue().get(RedisKeyConfig.AUTH_LOGIN_TOKEN + token),
                User.class
        );
        if (sysUser == null) {
            return R.fail("解析令牌失败");
        }
        OrderItem orderItem = orderItemDao.selectById(id);

        if (orderItem==null) {
            return R.fail("未找到商品");
        }
        List<OrderSku> orderSkuList = orderSkuDao.selectList(new LambdaQueryWrapper<>(OrderSku.class).eq(OrderSku::getOrderId, orderItem.getId()));
        if (orderSkuList.isEmpty()) {
            return R.fail("查询订单商品失败");
        }
        //组装数据返回前端

            OrderVo  orderVo = new OrderVo();
            BeanUtils.copyProperties(orderItem,orderVo);
            UserAddress userAddress = null;
            if (orderItem.getSnapAddress() != null && !orderItem.getSnapAddress().trim().isEmpty()) {
                try {
                    userAddress = JSON.parseObject(orderItem.getSnapAddress(), UserAddress.class);
                } catch (Exception e) {
                    log.warn("解析地址信息失败");
                    return R.fail("解析商品规格信息失败");
                }
            }
            orderVo.setUserAddress(userAddress);
        List<OrderSkuVo> orderSkuVoList = new ArrayList<>();
        for (OrderSku item : orderSkuList) {
            OrderSkuVo orderSkuVo = new OrderSkuVo();
            BeanUtils.copyProperties(item, orderSkuVo);
            orderSkuVo.setSalePrice(Price.IntToDecimal(item.getSalePrice()));
            orderSkuVoList.add(orderSkuVo);
        }
        orderVo.setSkuList(orderSkuVoList);
        orderVo.setSalePrice(Price.IntToDecimal(orderItem.getSalePrice()));
        orderVo.setTotalPrice(Price.IntToDecimal(orderItem.getTotalPrice()));
        orderVo.setFreightPrice(Price.IntToDecimal(orderItem.getFreightPrice()));
        return R.ok(orderVo);
    }

    @Override
    public R add(AddOrderDto dto, String token) {
        User sysUser = JSON.parseObject(
                template.opsForValue().get(RedisKeyConfig.AUTH_LOGIN_TOKEN + token),
                User.class
        );
        if (sysUser == null) {
            return R.fail("解析令牌失败");
        }
        if (dto.getTotalPrice().compareTo(dto.getSpuPrice().add(dto.getShipping())) != 0) {
            return R.fail("订单总价不匹配");
        }
        Long userId = sysUser.getId();

        // Step 2: 参数校验
        if (dto.getAddressId() == null || dto.getSpuList() == null || dto.getSpuList().isEmpty()) {
            return R.fail("参数缺失：请检查收货地址和商品列表");
        }
        String orderNo = Price.generateOrderNo();


        try {
            // Step 3: 查询收货地址
            UserAddress address = userAddressDao.selectById(dto.getAddressId());
            if (address == null) {
                return R.fail("收货地址不存在");
            }

            // Step 4: 提取商品信息
            List<AddCartDto> items = dto.getSpuList(); // ✅ 修正：使用 AddCartDto

            List<Long> spuIds = items.stream()
                    .map(AddCartDto::getSpuId)
                    .filter(Objects::nonNull)
                    .collect(Collectors.toList());
            List<Long> skuIds = items.stream()
                    .map(AddCartDto::getSkuId)
                    .filter(id -> id != null && id > 0)
                    .collect(Collectors.toList());

            Map<Long, Spu> spuMap = Collections.emptyMap();
            if (!spuIds.isEmpty()) {
                List<Spu> spus = spuDao.selectBatchIds(spuIds);
                spuMap = spus.stream().collect(Collectors.toMap(Spu::getId, Function.identity()));
            }

            Map<Long, Sku> skuMap = Collections.emptyMap();
            if (!skuIds.isEmpty()) {
                List<Sku> skus = skuDao.selectBatchIds(skuIds);
                skuMap = skus.stream().collect(Collectors.toMap(Sku::getId, Function.identity()));
            }
           String addressJson = JSON.toJSONString(address);


            // Step 5: 验证商品 & 检查库存 & 计算总金额
            List<OrderSku> orderSkus = new ArrayList<>();
            OrderItem orderItem = new OrderItem();
            orderItem.setOrderNo(orderNo);
            orderItem.setUserId(userId);
            orderItem.setTotalPrice(Price.YuanToCent(dto.getTotalPrice()));
            orderItem.setSalePrice(Price.YuanToCent(dto.getSpuPrice()));
            orderItem.setFreightPrice(Price.YuanToCent(dto.getShipping()));
            orderItem.setSnapAddress(addressJson);
            orderItem.setStatus(1); // 1=未支付
            // Step 9: 写入数据库
            orderItemDao.insert(orderItem);
            for (AddCartDto item : items) {
                Long spuId = item.getSpuId();
                Long skuId = item.getSkuId();
                Integer quantity = item.getQuantity();

                if (quantity <= 0) {
                    return R.fail("商品数量无效");
                }

                Spu spu = spuMap.get(spuId);
                if (spu == null) {
                    return R.fail("商品不存在：" + spuId);
                }

                Sku sku = null;
                // ✅ 价格转为 Integer（单位：分）
                long price = spu.getSalePrice();
                if (skuId != null && skuId > 0) {
                    sku = skuMap.get(skuId);
                    if (sku == null || !spuId.equals(sku.getSpuId())) {
                        return R.fail("SKU 不属于该 SPU 或不存在");
                    }
                    if (sku.getStock() < quantity) {
                        return R.fail(spu.getTitle() + " 库存不足");
                    }
                    price = sku.getSalePrice();
                } else {
                    if (spu.getStock() < quantity) {
                        return R.fail(spu.getTitle() + " 库存不足");
                    }
                }



                // 构建 OrderSku
                if (sku != null) {
                    OrderSku orderSku = new OrderSku();
                    String skuJson = JSON.toJSONString(sku);

                    orderSku.setId(0L);
                    orderSku.setOrderId(orderItem.getId());
                    orderSku.setOrderNo(orderNo);
                    orderSku.setSpuId(spuId);
                    orderSku.setSkuId(skuId);
                    orderSku.setSnapSku(skuJson);
                    orderSku.setSnapTitle(sku.getTitle());
                    orderSku.setQuantity(Long.valueOf(quantity));
                    orderSku.setSalePrice(price);
                    orderSku.setStatus(1);
                    orderSku.setUserId(userId.intValue());
                    orderSkuDao.insert(orderSku);
                }
            }
            // Step 10: 扣减库存


            // Step 11: 清除购物车


            // Step 12: 返回结果
            Map<String, Object> result = new HashMap<>();
            result.put("orderNo", orderNo);
            return R.ok(result);

        } catch (Exception e) {
            log.error("创建订单失败", e);
            return R.fail("系统繁忙，请稍后再试");
        }
    }
}

